package com.ifly.task.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.ifly.task.anno.ExcelSelectedResolve;
import com.ifly.task.handler.SelectedSheetWriteHandler;
import com.ifly.task.mapper.CountryConvertMapper;
import com.ifly.task.mapper.UserConvertMapper;
import com.ifly.task.pojo.Country;
import com.ifly.task.pojo.User;
import com.ifly.task.repository.CountryRepository;
import com.ifly.task.repository.UserRepository;
import com.ifly.task.util.EasyExcelUtil;
import com.ifly.task.vo.CountryExcelVo;
import com.ifly.task.vo.UserExcelVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: easyExcel
 * @description:
 * @author: xuYao2
 * @create: 2022-07-29 15:27
 **/
@RestController
@RequestMapping("excel")
@Slf4j
public class EasyExcelController {

    private final UserRepository userRepository;
    private final CountryRepository countryRepository;

    public EasyExcelController(UserRepository userRepository, CountryRepository countryRepository){
        this.userRepository = userRepository;
        this.countryRepository = countryRepository;
    }

    @GetMapping("/export")
    public void write(HttpServletResponse response) throws IOException {

        // 设置响应头
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 设置防止中文名乱码
        String filename = URLEncoder.encode(DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss"), "utf-8");
        // 文件下载方式(附件下载还是在当前浏览器打开)
        response.setHeader("Content-disposition", "attachment;filename=" +
            filename + ".xlsx");

        // easyExcel 获取写出工具
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
        // 设置下拉列表
        Map<Integer, ExcelSelectedResolve> selectedMap = EasyExcelUtil.resolveSelectedAnnotation(UserExcelVo.class);

        List<User> userList = userRepository.findAll();
        List<Country> countryList = countryRepository.findAll();

        excelWriter.write(userList,
            EasyExcel.writerSheet(0, "用户")
                .registerWriteHandler(new SelectedSheetWriteHandler(selectedMap))
                .head(UserExcelVo.class)
                .build());

        excelWriter.write(countryList,
            EasyExcel.writerSheet(1, "国家").head(CountryExcelVo.class).build());

        // 写入数据到excel
        excelWriter.finish();


    }

    @Resource
    private UserConvertMapper userConvertMapper;

    @Resource
    private CountryConvertMapper countryConvertMapper;

    @PostMapping("/import")
    public void importExcel(@RequestParam("file") MultipartFile file) throws IOException {
        List<UserExcelVo> userList = EasyExcel.read(file.getInputStream())
            .head(UserExcelVo.class)
            .sheet(0)
            .doReadSync();

        List<CountryExcelVo> countryList = EasyExcel.read(file.getInputStream())
            .head(CountryExcelVo.class)
            .sheet(1)
            .doReadSync();

        log.info("userList: {}", userList);
        log.info("country: {}", countryList);

        // mapStruct对象转换
        List<User> toUserList = userConvertMapper.toUserList(userList);
        List<Country> toCountryList = countryConvertMapper.toCountryList(countryList);

        // 数据库中的数据
        List<User> userListInDataBase = userRepository.findAll();
        List<Country> countryListInDataBase = countryRepository.findAll();

        // 处理导出的excel中被删除的数据
        List<Long> userIdsInDataBase = userListInDataBase.stream().map(User::getId).collect(Collectors.toList());
        List<Long> userIdsInExcel = toUserList.stream().map(User::getId).collect(Collectors.toList());
        // excel中没有，但数据库中存在的id，是做了删除操作的
        userIdsInDataBase.removeAll(userIdsInExcel);
        userIdsInDataBase.forEach(userRepository::deleteById);

        List<Long> countryIdsInDataBase = countryListInDataBase.stream().map(Country::getId).collect(Collectors.toList());
        List<Long> countryIdsInExcel = toCountryList.stream().map(Country::getId).collect(Collectors.toList());
        countryIdsInDataBase.removeAll(countryIdsInExcel);
        countryIdsInDataBase.forEach(countryRepository::deleteById);

        userRepository.saveAll(toUserList);
        countryRepository.saveAll(toCountryList);

    }


}
